﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Xml;
using System.Collections;
using OneRed.Draw;
using System.Collections.ObjectModel;
using OneRed.Data;
using System.Text;
using System.Text.RegularExpressions;

namespace OneRed.File
{
    public class FileOprate
    {
        private static string psXmlFileName = "";
        private static XmlElement root = null, mainElement = null;// subElement = null;
        private static XmlDocument xmldoc;
        #region 文件夹操作
        /// <summary>
        /// 打开文件夹对话框并返回路径
        /// </summary>
        /// <param name="sDescription">选择文件对话框的描述信息</param>
        /// <param name="blShowNewButton">是否显示新建文件按钮</param>
        /// <returns></returns>
        public static string ChooseFolder(string sDescription, bool blShowNewButton)
        {
            System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog
            {
                Description = sDescription,
                ShowNewFolderButton = blShowNewButton
            };
            if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                return fbd.SelectedPath;
            }
            else
            {
                return "err";
            }
        }

        /// <summary>
        /// 读取指定目录下全部的txt文件路径
        /// </summary>
        /// <param name="sFolderPath">指定文件夹</param>
        /// <param name="lsArry">文件夹下全部txt文件的路径</param>
        /// <returns>是否读取数据成功</returns>
        public static bool ReadFileFromFolder(string sFolderPath, out List<string> lsArry)
        {
            lsArry = new List<string>();
            if (!Directory.Exists(sFolderPath))
            {
                return false;
            }
            //C#遍历指定文件夹中的所有文件  
            DirectoryInfo TheFolder = new DirectoryInfo(sFolderPath);
            //遍历文件夹 
            FileInfo[] files = TheFolder.GetFiles();//获取文件夹下的所有文件
            string fileName;
            for (int i = 0; i < files.Length; i++)
            {
                fileName = files[i].FullName.ToLower();
                if (fileName.EndsWith(".txt") || fileName.EndsWith(".dclg"))
                {
                    lsArry.Add(fileName);
                }
            }
            return true;
        }
        public static bool FolderHaveChildren(string sFolderPath)
        {
            //C#遍历指定文件夹中的所有文件  
            DirectoryInfo TheFolder = new DirectoryInfo(sFolderPath);
            //遍历文件夹 
            FileInfo[] files = TheFolder.GetFiles();//获取文件夹下的所有文件
            if (files.Length == 0)
                return true;
            return false;
        }
        //清空文件时才能再删除文件夹
        public static bool ClearFolder(string sFolderPath)
        {
            List<string> lsTxtFilePath;
            if (FileOprate.ReadFileFromFolder(sFolderPath, out lsTxtFilePath))
            {
                foreach (string sTextPath in lsTxtFilePath)
                {
                    System.IO.File.Delete(sTextPath);//.Copy(sTextPath, System.IO.Path.Combine(sProjectPath, "OriData") + @"\" + sTextPath.Substring(sTextPath.LastIndexOf('\\')), true);
                }
            }
            return false;
        }
        /// <summary>
        /// 新建文件夹
        /// </summary>
        /// <param name="sFolderPath">文件夹路径</param>
        /// <returns>false 文件夹已经存在 true 新建文件夹成功</returns>
        public static bool CreatFolder(string sFolderPath)
        {
            try
            {
                if (Directory.Exists(sFolderPath))
                {
                    //return false;//文件夹已经存在则删除文件夹
                    Directory.Delete(sFolderPath, true);
                }
                Directory.CreateDirectory(sFolderPath);
                return true;//创作文件成功
            }
            catch
            {
                return false;
            }
        }

        //打开文件
        public static string OpenFileDialog()
        {
            System.Windows.Forms.OpenFileDialog openFileDialog = new System.Windows.Forms.OpenFileDialog();
            openFileDialog.Filter = "项目文件 (*.pclg)|*.pclg|数据文件 (*.dclg)|*.dclg|图像文件 (*.mclg)|*.mclg";
            openFileDialog.CheckPathExists = true;
            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                return openFileDialog.FileName;
            }
            else
            {
                return "err";
            }
        }
        #endregion

        #region Txt操作
        /// <summary>
        /// 从标准的数据格式源数据中读取数据
        /// </summary>
        /// <param name="sTxtPath"></param>
        /// <param name="blStanderDataOri"></param>//fale 表示标准处理过的源数据 true为没处理过的最原始的数据
        /// <returns></returns>
        public static bool ReadTxtFromSaveData(string sTxtPath)//, ObservableCollection<FormatData> standerJournals
        {
            string path = sTxtPath;
            FormatData sj;

            if (!System.IO.File.Exists(path))
            {
                return false;
            }
            using (FileStream fs = new FileStream(path, FileMode.Open))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    string sTemp = "";
                    string[] sColum;
                    while (!sr.EndOfStream)
                    {
                        sTemp = sr.ReadLine();
                        if (sTemp.Length < 1)
                        {
                            continue;
                        }

                        sColum = sTemp.Split('\t').ToArray();
                        sj = new FormatData();
                        sj.gID = sColum[0].Trim();
                        sj.sTitle = sColum[1].Trim();
                        sj.sAuthor = sColum[2].Trim();
                        sj.sJournal = sColum[3].Trim();
                        sj.sKeywords = sColum[4].Trim();
                        sj.sCites = sColum[5].Trim();
                        sj.sAuthorOrgan = sColum[6].Trim();
                        sj.sYear = sColum[7].Trim();
                        sj.sSummary = sColum[8].Trim();
                        FormatDataCollection.addData(sj);
                        //standerJournals.Add(sj);
                    }
                }
                return true;
            }
        }
        public static string readYearsFromList(ObservableCollection<FormatData> sj, SortedList<string, string> slYear, SortedList<string, double> slYearsPercent)
        {
            slYearsPercent.Clear();
            string sreturn = null;
            foreach (FormatData sjTemp in sj)
            {
                if (string.IsNullOrEmpty(sjTemp.sYear))
                    continue;

                if (slYear.ContainsKey(sjTemp.sYear))
                {
                    string[] svlue = slYear[sjTemp.sYear].Split('|');
                    int iautor = sjTemp.sAuthor.TrimEnd(';').TrimEnd('|').Split(new char[] { ';', '|' }).Count();
                    slYear[sjTemp.sYear] = (double.Parse(svlue[0]) + 1).ToString() + "|" + (double.Parse(svlue[1]) + iautor).ToString();

                    //slYear[sjTemp.sYear] = (double.Parse(slYear[sjTemp.sYear]) + 1).ToString();
                }
                else
                {
                    //求出作者数量，文档数量默认为1
                    int iautor = sjTemp.sAuthor.TrimEnd(';').TrimEnd('|').Split(new char[] { ';', '|' }).Count();
                    slYear.Add(sjTemp.sYear, "1|" + iautor.ToString());
                }
            }
            if (slYear.Count <= 0)
                return sreturn;
            else
            {
                sreturn += "年份范围从" + Enumerable.First(slYear).Key + "年至" + Enumerable.Last(slYear).Key + "年，有数据年度共" + slYear.Count + "年。\n";
                //double yearNumTemp = 0.0;
                //string sYears = "年    份\t";//存在表格中一行年份值
                //string sYearsNum = "数    量\t";//存入每年的数值
                //string sYearsPer = "百分比\t";//存放每年的比例值
                //string sYearsPerSum = "累积比\t";//累积比
                //foreach (KeyValuePair<string, string> key in slYear)
                //{
                //    double dpercentTemp = Math.Round(double.Parse(key.Value) * 1.0 / sj.Count * 100, 2);
                //    slYearsPercent.Add(key.Key, dpercentTemp);
                //    yearNumTemp += double.Parse(key.Value);
                //    sYears += key.Key + "\t";
                //    sYearsNum += key.Value + "\t";
                //    sYearsPer += dpercentTemp + "%\t";
                //    sYearsPerSum += Math.Round(yearNumTemp * 1.0 / sj.Count * 100, 2) + "%\t";
                //}
                //sreturn += sYears + "\n" + sYearsNum + "\n" + sYearsPer + "\n" + sYearsPerSum + "\n";
                sreturn += "时间:" + DateTime.Now.ToLocalTime();
                return sreturn;
            }
        }

        public static SortedList<string, string> SpliceYears(SortedList<string, string> slYear, string start, string end, string sSplice)
        {
            SortedList<string, string> retlYear = new SortedList<string, string>();
            var vTemp = slYear.Where(y => Int32.Parse(y.Key) >= Int32.Parse(start) && Int32.Parse(y.Key) <= Int32.Parse(end)).ToList();
            string sYear = "";
            int iVlue1 = 0;
            int iVlue2 = 0;
            for (int iy = 0; iy < vTemp.Count; iy++)
            {
                var vVlue = vTemp[iy].Value.Split('|');

                if (iy % Int32.Parse(sSplice) == 0)
                {
                    if (string.IsNullOrEmpty(sYear))
                    {
                        sYear += vTemp[iy].Key + "-";
                    }
                    else
                    {
                        if (vTemp[iy - 1].Key == sYear.TrimEnd('-'))
                        {
                            sYear = vTemp[iy - 1].Key;
                        }
                        else
                        {
                            sYear += vTemp[iy - 1].Key;
                        }

                        retlYear.Add(sYear, iVlue1 + "|" + iVlue2);
                        //年度的开头
                        sYear = "";
                        sYear += vTemp[iy].Key + "-";

                    }

                    iVlue1 = Int32.Parse(vVlue[0]);
                    iVlue2 = Int32.Parse(vVlue[1]);
                }
                else
                {
                    //中间值的时候
                    iVlue1 += Int32.Parse(vVlue[0]);
                    iVlue2 += Int32.Parse(vVlue[1]);
                }

                if (iy == vTemp.Count - 1)
                {
                    if (vTemp[iy].Key == sYear.TrimEnd('-'))
                    {
                        sYear = vTemp[iy].Key;
                    }
                    else
                    {
                        sYear += vTemp[iy].Key;
                    }
                    retlYear.Add(sYear, iVlue1 + "|" + iVlue2);
                }
                //iy += Int32.Parse(sSplice);
            }
            return retlYear;
        }

        /// <summary>
        /// 写入数据到指定文件
        /// </summary>
        /// <param name="sTxtPath">文件路径</param>
        /// <param name="sContent">写入内容</param>
        /// <returns></returns>
        public static bool WriteTxt(string sTxtPath, string sContent, FileMode fileMode)
        {
            string slinelast = "";
            if (System.IO.File.Exists(sTxtPath))
            {
                using (StreamReader sr = new StreamReader(sTxtPath))
                {
                    while (sr.Peek() > 0)
                    {
                        slinelast = sr.ReadLine();
                    }
                }

                if (slinelast != sContent)
                {
                    using (FileStream fs = new FileStream(sTxtPath, fileMode))
                    {
                        using (StreamWriter sw = new StreamWriter(fs))
                        {
                            sw.WriteLine(sContent);
                        }
                    }
                }
            }
            else
            {
                using (FileStream fs = new FileStream(sTxtPath, fileMode))
                {
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        sw.WriteLine(sContent);
                    }
                }
            }
            return true;
        }
        //写入大量数据，不自动换行
        public static bool WriteTxtNoWrap(string sTxtPath, string sContent, FileMode fileMode)
        {
            using (FileStream fs = new FileStream(sTxtPath, fileMode))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    sw.Write(sContent);
                }
                return true;
            }
        }
        /// <summary>
        /// 读取指定文本文件内的全部数据，依据正确的编码格式
        /// </summary>
        /// <param name="sTxtPath">文本文件所在路径</param>
        /// <returns>文本内全部内容</returns>
        public static string readTxt(string sTxtPath)
        {
            string path = sTxtPath;
            if (!System.IO.File.Exists(path))
            {
                return "err";
            }
            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                #region 读取的数进行正确的编码，从而正确读取utf8,unicode,ansi等格式的数据
                Encoding txtEnc = GetTxtEncodingType.GetEncoding(path);
                int fsLen = (int)fs.Length;
                byte[] heByte = new byte[fsLen];
                int r = fs.Read(heByte, 0, heByte.Length);
                string sAll = txtEnc.GetString(heByte);//sr.ReadToEnd());//读取全部数据
                #endregion
                return sAll;
            }
        }
        #endregion
        #region XML操作
        /// <summary>
        /// 查看该路径下XML文件是否存在，不存在则创建，存在则打开
        /// </summary>
        /// <param name="sXmlFileName">保存XML文件的路径及名称</param>
        /// <returns></returns>
        public static bool XMLfind(string sXmlFileName)
        {
            psXmlFileName = sXmlFileName;
            try
            {
                if (!System.IO.File.Exists(psXmlFileName))
                {
                    xmldoc = new XmlDocument();
                    //加入XML的声明段落,<?xml version="1.0" encoding="gb2312"?>
                    XmlDeclaration xmldecl;
                    xmldecl = xmldoc.CreateXmlDeclaration("1.0", "UTF-8", null);
                    xmldoc.AppendChild(xmldecl);

                    //加入一个根元素
                    root = xmldoc.CreateElement("", "OneRedRoot", "");
                    xmldoc.AppendChild(root);
                    xmldoc.Save(psXmlFileName);
                }
                else
                {
                    xmldoc = new XmlDocument();
                    xmldoc.Load(psXmlFileName);
                    root = xmldoc.DocumentElement;
                }
                return true;
            }
            catch
            {
                return false;
            }

        }
        /// <summary>
        /// 将相应的节点及值添加到xml中
        /// </summary>
        /// <param name="sname"></param>
        /// <param name="scontent"></param>
        public static void XMLaddElement(Hashtable htKeyValue)
        {
            try
            {
                //---  新建项开始 ----
                foreach (DictionaryEntry keyp in htKeyValue)
                {
                    mainElement = xmldoc.CreateElement(keyp.Key.ToString());
                    mainElement.InnerText = keyp.Value.ToString();
                    root.AppendChild(mainElement);
                    xmldoc.Save(psXmlFileName);
                }
                //---  新建一本书完成 ----
            }
            catch
            {
            }
        }
        //按指定的节点名返回其内容
        public static string XMLgetContentByName(string sControlName)
        {
            try
            {
                mainElement = (XmlElement)root.SelectSingleNode("/OneRedRoot/" + sControlName);
                //---  此时修改这本书的价格 -----
                string s = mainElement.InnerText.ToString();
                if (s.Length < 1)
                    s = "err";
                return (s);

            }
            catch
            {
                return "err";
            }
        }
        //修订节点的值
        public static void XMLchangElement(string sType, string sNewContent)
        {
            try
            {
                //---  下面对《哈里波特》做一些修改。 ----
                //---  查询找《哈里波特》----
                mainElement = (XmlElement)root.SelectSingleNode("/OneRedRoot/" + sType);
                //---  此时修改这本书的价格 -----
                mainElement.InnerText = sNewContent;//getElementsByTagName返回的是NodeList，所以要跟上item(0)。另外，GetElementsByTagName("price")相当于SelectNodes(".//price")。            
                //---  另外还想加一个属性id，值为B01 ----
                //mainElement.SetAttribute("id", "B01");
                //---  对《哈里波特》修改完成。 ----
                xmldoc.Save(psXmlFileName);
            }
            catch
            {
            }
        }

        /// <summary>
        /// 将标准的转换后的XML数据读取到项目的列表源中去
        /// </summary>
        /// <param name="sPath">标准XML源数据文件夹</param>
        /// <param name="listSJ">项目源数据</param>
        public static void readDataFromStdXml2ProjectList(string sPath)//, ObservableCollection<FormatData> listSJ
        {
            //C#遍历指定文件夹中的所有文件  
            DirectoryInfo TheFolder = new DirectoryInfo(System.IO.Path.Combine(sPath, @"StdOriData"));
            //遍历文件夹 
            foreach (FileInfo file in TheFolder.GetFiles("*.dclg"))
            {
                xmldoc = new XmlDocument();
                xmldoc.Load(file.FullName);
                XmlNodeList nodeList = xmldoc.SelectNodes("ImptDatas/Bibliography");
                FormatData s;
                foreach (XmlNode xn in nodeList)
                {
                    XmlNodeList nodeListSec = xn.ChildNodes;
                    s = new FormatData();
                    s.gID = Guid.NewGuid().ToString();
                    foreach (XmlNode xns in nodeListSec)
                    {
                        switch (xns.Name)
                        {
                            //case "DT":
                            //    s.sType = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                            //    break;
                            case "TI":
                                s.sTitle = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                                break;
                            case "PY":
                                s.sYear = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                                break;
                            case "KWs":
                                s.sKeywords = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                                break;
                            case "AB":
                                s.sSummary = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n\t]+", "|");
                                break;
                            case "AU":
                                s.sAuthor = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                                break;
                            case "AD":
                                s.sAuthorOrgan = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                                break;
                            case "SO":
                                s.sJournal = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                                break;
                            //case "IS":
                            //    s.sPeriod = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                            //    break;
                            //case "OP":
                            //    s.sPages = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                            //    break;
                            //case "CN":
                            //    s.sCN = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                            //    break;
                            //case "SN":
                            //    s.sIssn = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                            //    break;
                            case "CLC":
                                s.sCLCode = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                                break;
                            //case "SUC":
                            //    s.sSujectClass = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                            //    break;
                            case "CIs":
                                s.sCites = Regex.Replace((xns as XmlElement).InnerText.ToString(), @"[\r\n]+", "|");
                                break;
                                //s += xns.Name + "|" + (xns as XmlElement).InnerText.ToString() + "\t";
                        }
                    }
                    FormatDataCollection.addData(s);
                }
            }
        }

        #endregion
        //打开文件夹     

    }
}
